﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="InjectedClaimsAuthenticationManager.cs" company="AzureContrib (Open source library http://azurecontrib.codeplex.com)">
//   Microsoft Public License (Ms-PL)
// </copyright>
// <summary>
//   Simple authentication manager which delegates to the real <see cref="IAuthenticationService" />
// </summary>
// --------------------------------------------------------------------------------------------------------------------

using System;

using AzureContrib.WindowsAzure.Diagnostics;
using AzureContrib.WindowsAzure.Properties;
using AzureContrib.WindowsAzure.ServiceRuntime.ServiceLocation;

using Microsoft.IdentityModel.Claims;

namespace AzureContrib.WindowsAzure.AccessControlService
{
	/// <summary>
	/// Simple authentication manager which delegates to the real <see cref="IAuthenticationService"/>
	/// </summary>
	public class InjectedClaimsAuthenticationManager : ClaimsAuthenticationManager
	{
		private static IBuilder builder;

		/// <summary>
		/// Initializes a new instance of the <see cref="InjectedClaimsAuthenticationManager"/> class. 
		/// </summary>
		public InjectedClaimsAuthenticationManager()
		{
			// Perhaps not the prettiest of solutions but this little module is not created through the container.
			Builder.BuildUp(this);

			var authentiationServiceName = AuthenticationService.GetType().FullName;
			Trace.Information(Strings.AuthenticationServiceInUse.F(authentiationServiceName));
		}

		/// <summary>
		/// Gets or sets the <see cref="IBuilder"/>.
		/// </summary>
		/// <remarks>Please do no abuse this power!</remarks>
		/// <remarks>The purpose is to enable Dependency Injection on classes that are not createable through a factory!</remarks>
		public static IBuilder Builder
		{
			internal get
			{
				if (builder == null)
				{
					throw new Exception(Strings.BuilderIsMissing.F(typeof(InjectedClaimsAuthenticationManager)));
				}

				return builder;
			}

			set
			{
				builder = value;
			}
		}

		/// <summary>
		/// Gets or sets the <see cref="ITrace"/> to use inside of this instance.
		/// </summary>
		public ITrace Trace { get; set; }

		/// <summary>
		/// Gets or sets the <see cref="IAuthenticationService"/> which separates this module from the implementation.
		/// </summary>
		public IAuthenticationService AuthenticationService { protected get; set; }

		/// <summary>
		/// Forwards a call to the <see cref="IAuthenticationService.Authenticate"/>.
		/// </summary>
		/// <param name="resourceName">The resource to access.</param>
		/// <param name="incomingPrincipal">The incoming Principal.</param>
		/// <returns>
		/// True if access is granted.
		/// </returns>
		public override IClaimsPrincipal Authenticate(string resourceName, IClaimsPrincipal incomingPrincipal)
		{
			return AuthenticationService.Authenticate(resourceName, incomingPrincipal);
		}
	}
}